跳到主要内容

01-02 Make和Makefile

01 Make和Makefile

思考:什么是make?为什么需要make?

make是一个应用程序:解析源程序之间的依赖关系;根据依赖关系自动维护编译工作;执行宿主操作系统中的各种命令。

makefile是一个描述文件:定义一系列的规则来指定源文件编译的先后顺序;拥有特定的语法规则,支持函数定义和函数调用;能够直接集成操作系统中的各种命令

make和makefile之间的关系:makefile中的描述用于指导make程序如何完成工作;make根据makefile中的规则执行命令,最后完成编译输出。

  • 最简单的makefile示例

    注意:目标后的命令需要用Tab键('\t')隔开!

  • make程序的使用示例

make -f mf.txt hello

功能说明:以hello关键字作为目标查找mf.txt文件,并执行hello处的命令。

  • make程序的简写实例
make hello

功能说明:以hello关键字作为目标查找makefile或Makefile文件,并执行hello处的命令。

make

功能说明:查找makefile或Makefile文件中最顶层目标,并执行最顶层目标的命令。

编程实验:makefile初探

hello : 
echo "hello makefile"

test :
echo "test"
pwd
ls

小结

  • make只是一个特殊功能的应用程序
  • make用于根据指定的目标执行相应的命令
  • makefile用于定义目标和实现目标所需的命令
  • makefile有特定的语法规则,支持函数定义和调用

02 初识makefile的结构

makefile的意义:makefile用于定义源文件间的依赖关系,makefile说明如何编译各个源文件并生成可执行文件

依赖的定义:

targets : prerequisites ; command1
'\t' command2
  • makefile中的元素含义

    • targets
      • 通常是需要生成的目标文件名
      • make所需执行的命令名称
    • prerequisites:当前目标所以依赖的其它目标或文件
    • command:完成目标所需执行的命令
  • 规则中的注意事项

    • target可以包含多个目标:使用空格对多个目标进行分隔
    • prerequisites可以包含多个依赖:使用空格对多个依赖进行分隔
    • [TAB]键:'\t'
      • 每一个命令行必须以[TAB]字符开始
      • [TAB]字符告诉make此行是一个命令行
    • 续行符\:可以将内容分开写到下一行,提高可读性
  • 一个makefile的依赖示例

all : test
echo "make all"
test :
echo "make test"

  • 依赖规则
    • 当目标对应的文件不存在,执行对应命令
    • 当依赖在时间上比目标更新,执行对应命令
    • 当依赖关系连续发生时,对比依赖链上的每一个目标

小技巧:makefile中可以在命令前加上@符,作用为命令无回显。

编程实验:makefile的规则依赖

all : test
@echo "make all"

test :
@echo "make test"
  • 第一个make的编译案例
hello.out : main.o func.o
gcc -o hello.out main.o func.o
main.o : main.c
gcc -o main.out -c main.c
func.o : func.c
gcc -o func.o -c func.c
  • 小技巧 工程开发中可以将最终可执行文件名和all同时作为makefile中第一条规则的目标
hello.out all : main.o func.o
gcc -o hello.out main.o func.o

编程实验:初探make编译

//func.c
#include "stdio.h"

void foo() {
printf("void foo() : hello makefile\n");
}
//main.c

extern void foo();

int main() {
foo();
return 0;
}
hello.out all : func.o main.o
gcc -o hello.out func.o main.o

func.o : func.c
gcc -o func.o -c func.c

main.o : main.c
gcc -o main.o -c main.c

小结

  • makefile用于定义源文件间的依赖关系
  • makefile说明如何编译各个源文件并生成可执行文件
  • makefile中的目标之间存在连续依赖关系
  • 依赖存在并且命令执行成功是目标完成的充要条件